
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <time.h>
#include <signal.h>
#include <pthread.h>
#include <sys/timerfd.h>
#include <errno.h>


#define UDS_ADDR "/var/run/uds_test.socket"
#define MAX_BUFF_LEN 1500

/* 本机位server    */
#define MSG_DEST_ADDR    1
#define MSG_LOCAL_ADDR   8  


#define ZOS_MEM_GOD \
        "                                 _ooOoo_\n"\
        "                                o8888888o\n"\
        "                                88\" . \"88\n"\
        "                                (| -_- |)\n"\
        "                                O\\  =  /O\n"\
        "                             ____/`---'\\____\n"\
        "                           .'  \\\\|     |//  `.\n"\
        "                          /  \\\\|||  :  |||//  \\\n"\
        "                         /  _||||| -:- |||||-  \\\n"\
        "                         |   | \\\\\\  -  /// |   |\n"\
        "                         | \\_|  ''\\---/''  |   |\n"\
        "                         \\  .-\\__  `-`  ___/-. /\n"\
        "                       ___`. .'  /--.--\\  `. . __\n"\
        "                    ."" '<  `.___\\_<|>_/___.'  >'"".\n"\
        "                   | | :  `- \\`.;`\\ _ /`;.`/ - ` : | |\n"\
        "                   \\  \\ `-.   \\_ __\\ /__ _/   .-` /  /\n"\
        "              ======`-.____`-.___\\_____/___.-`____.-'======\n"\
        "                                 `=---='\n"\
        "              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  
int g_ack_msg_cnt = 0;

typedef struct uds_server_struct
{
    int listen_fd;
    int child_fd;  /*暂时支持一股额client */
    struct sockaddr_un addr;
}UDS_SERVER_ST;

UDS_SERVER_ST g_uds_server;

int uds_receive(char* pbuf, unsigned int buf_len);
int uds_send(char* pbuf, unsigned int buf_len);
int uds_server_init(unsigned char* mac_addr, unsigned int mac_addr_len);



void *uds_thread_entry(void *arg)
{
    fd_set read_fds;
    struct timeval timeout;
    int fds_max = g_uds_server.listen_fd;
    int ret = -1;
    int new_fd = -1;
    int addr_len = 0;
    int buf_len = MAX_BUFF_LEN;
    char buff[MAX_BUFF_LEN];
    
    //printf("uds thread entry");
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    while(1)
    {

        FD_ZERO(&read_fds);
        FD_SET(g_uds_server.listen_fd, &read_fds); 

        if (g_uds_server.child_fd > 0)
        {
            FD_SET(g_uds_server.child_fd, &read_fds);
            fds_max = (fds_max < g_uds_server.child_fd) ? g_uds_server.child_fd : fds_max; 
        }

        printf("server select ...fds_max=%u\n",fds_max);
        
        ret = select(fds_max + 1, &read_fds, NULL, NULL, &timeout);
        switch(ret)
        {
            case 0:
                printf("server select time out...\n");
                break;
            case -1:
                perror("server select failed!\n");
                break;
            default:
            {
                if(FD_ISSET(g_uds_server.listen_fd, &read_fds))
                {
                    /* 模拟网卡接收中断 */
                    new_fd = accept(g_uds_server.listen_fd, (struct sockaddr *)&g_uds_server.addr, &addr_len);
                    g_uds_server.child_fd = new_fd;   
                    printf("new client [%u] had been connencted.\n", new_fd);
                }

                if(FD_ISSET(g_uds_server.child_fd, &read_fds))
                {
                    /* 模拟网卡接收中断*/
                    printf("server receive data successfully,child fd=[%u]...\n",g_uds_server.child_fd);
                    ret = uds_receive(buff, buf_len);
                    if (ret > 0)
                    {
                        printf("%s\n",buff);
                        ret = uds_send(buff, buf_len);
                    }
                }

            }
        }
        
        sleep(1);
    }
    
    /* 子线程模拟网卡接收中断 */
    //ecm_ethernet_irq_handler();
  
    return ((void *)0);
}

void  sig_handler(int signo)
{
    
    //printf("timer_signal function! %d\n", signo);
    //ecm_systick_irq_handler();
    
}

int posix_timer_init(void)
{
    int ret;
    timer_t timer;
    struct sigevent evp;
    struct timespec spec;
    struct itimerspec time_value;

    evp.sigev_value.sival_ptr = &timer;
    /*定时器到期时，会产生一个信号*/
    evp.sigev_notify = SIGEV_SIGNAL; 
    evp.sigev_signo = SIGUSR1;
    signal(SIGUSR1, sig_handler);

    /*时钟源选CLOCK_MONOTONIC主要是考虑到系统的实时时钟可能会在
    程序运行过程中更改，所以存在一定的不确定性，而CLOCK_MONOTONIC
    则不会，较为稳定*/
    ret = timer_create(CLOCK_MONOTONIC, &evp, &timer);
    if(0 != ret)
    {
        perror("timer_create");
    }

    time_value.it_interval.tv_sec = 0;      /*每毫秒触发一次*/
    time_value.it_interval.tv_nsec = 1000000;
    clock_gettime(CLOCK_MONOTONIC, &spec);         
    time_value.it_value.tv_sec = spec.tv_sec + 3;      /*3秒后启动*/
    time_value.it_value.tv_nsec = spec.tv_nsec + 0;

    ret = timer_settime(timer, CLOCK_MONOTONIC, &time_value, NULL);
    if(0 != ret)
    {
        perror("timer_settime");
    }

    return ret;
}

int uds_server_init(unsigned char* mac_addr, unsigned int mac_addr_len)
{
    int sockfd, new_fd;
    struct sockaddr_un src;
    int ret;
    int len;
    pthread_t tid;

    unlink(UDS_ADDR);
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockfd < 0) 
    {
        perror("server create socket failed");
    }

    memset(&src, 0, sizeof (src));
    src.sun_family = AF_UNIX;
    strcpy(src.sun_path, UDS_ADDR);
    
    len = offsetof(struct sockaddr_un, sun_path) + sizeof (UDS_ADDR);
    //len = sizeof(struct sockaddr_un);
    if (bind(sockfd, (struct sockaddr *)&src, len) < 0) 
    {
        perror ("server bind socket failed");
    }

    ret = listen(sockfd, 15);
    if (ret < 0) 
    {
        perror ("server listen socket failed");
    }

    g_uds_server.listen_fd = sockfd;
    g_uds_server.child_fd = -1;
    memcpy(&g_uds_server.addr,&src,sizeof(struct sockaddr_un));

    /* 创建线程pthread */
    if ((pthread_create(&tid, NULL,uds_thread_entry,NULL)) == -1)
    {
        printf("server create pthread error!\n");
        return 1;
    }


    return ret;
}


int uds_receive(char* pbuf, unsigned int buf_len)
{
    int ret = 0;

    ret = read(g_uds_server.child_fd, pbuf, buf_len);
    if (ret > 0)
    {
        printf("server receive data len =%u.\n",ret);
    }
    else
    {
        printf("Error[%d] when recieving Data:%s.\n",errno,strerror(errno));
    }
    
    return ret;
}

int uds_send(char* pkt_buf, unsigned int pkt_len)
{
    int ret = 0;
    
    ret = write(g_uds_server.child_fd, pkt_buf, pkt_len);
    if (0 < ret)
    {
        printf("server write data successfully...\n");
        return 0;
    }
    else
    {
        printf("server write error, ret=%d!\n",ret);
        return ret;
    }
}


int main(int argc,char *argv[])
{
    int ret;

    uds_server_init(NULL,0);

    
    while(1)
    {
   
        sleep(1);
    }

    close(g_uds_server.listen_fd);
    close(g_uds_server.child_fd);
    
    return 0;
}



